package com.zking.ssm.shiro;

import com.zking.ssm.biz.UserBiz;
import com.zking.ssm.model.User;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.Set;

/**
 * @author小李飞刀
 * @site www.javaxl.com
 * @company xxx公司
 * @create  2022-08-25 10:06
 */
public class MyRealm extends AuthorizingRealm {
    public UserBiz userBiz;

    public UserBiz getUserBiz() {
        return userBiz;
    }

    public void setUserBiz(UserBiz userBiz) {
        this.userBiz = userBiz;
    }

    /**
     * 授权
     * @param principals
     * @return
     * shiro-web.ini
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String userName = principals.getPrimaryPrincipal().toString();// 获取账户名
//        先从缓存中取，缓存中没有，再查询数据库，查询出数据放入缓存
        String cacheName1 = "user:role:"+userName;
        String cacheName2 = "user:per:"+userName;
//      从缓存中获取角色
        Set<String> roleIds = (Set<String>) EhcacheUtil.get(cacheName1, userName);
//        从缓存中获取权限
        Set<String> perIds = (Set<String>) EhcacheUtil.get(cacheName2, userName);
        if (roleIds == null || roleIds.size() == 0){
            roleIds = userBiz.selectRoleIdsByUserName(userName);
            System.out.println("从数据库中读取用户角色...");
            EhcacheUtil.put(cacheName1,userName,roleIds);
        }

        if (perIds == null || perIds.size() == 0){
            perIds = userBiz.selectPerIdsByUserName(userName);
            System.out.println("从数据库中读取用户权限...");
            EhcacheUtil.put(cacheName2,userName,perIds);
        }

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//      将当前登录的 权限 交给 shiro的授权器
        info.setStringPermissions(perIds);
//        将当前登录的 角色 交给 shiro的授权器
        info.setRoles(roleIds);
        return info;
    }

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     * shiro.ini
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName = token.getPrincipal().toString();
        User user = userBiz.queryUserByUserName(userName);
        AuthenticationInfo info =new SimpleAuthenticationInfo(
                user.getUsername(),
                user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()),
                this.getName() // realm的名字
        );
        return info;
    }
}
